﻿using System;
using System.Diagnostics;

namespace InfiniTec.Diagnostics
{
	/// <summary>
	/// This class simplifies the use of the <see cref="TraceSource"/> class by delegating a few methods.
	/// </summary>
	public sealed class Trace
	{
		private readonly TraceSource _Source;

		/// <summary>
		/// Initializes a new instance of the <see cref="Trace"/> class.
		/// </summary>
		/// <param name="sourceName">Name of the source to use</param>
		public Trace(string sourceName)
		{
			_Source = new TraceSource(sourceName);
		}

		/// <summary>
		/// Starts a logical operation operation.
		/// </summary>
		/// <returns></returns>
		public TraceOperation StartOperation(int id, string name)
		{
			return StartOperation(id, name, null);
		}

		/// <summary>
		/// Starts a logical operation operation.
		/// </summary>
		/// <returns></returns>
		public TraceOperation StartOperation(string name, params object[] args)
		{
			return new TraceOperation(this, 0, name, args);
		}

		/// <summary>
		/// Starts a logical operation operation.
		/// </summary>
		/// <returns></returns>
		public TraceOperation StartOperation(string name)
		{
			return StartOperation(0, name, null);
		}

		/// <summary>
		/// Starts a logical operation operation.
		/// </summary>
		/// <returns></returns>
		public TraceOperation StartOperation(int id, string name, params object[] args)
		{
			return new TraceOperation(this, id, name, args);
		}

		/// <summary>
		/// Gets the <see cref="TraceSource"/> used by this instance.
		/// </summary>
		/// <value>The source.</value>
		public TraceSource Source
		{
			get { return _Source; }
		}

		/// <summary>
		/// Gets or sets the id for the current Activity.
		/// </summary>
		/// <value>The activity id to use.</value>
		public static Guid ActivityId
		{
			get { return System.Diagnostics.Trace.CorrelationManager.ActivityId; }
			set { System.Diagnostics.Trace.CorrelationManager.ActivityId = value; }
		}

		public void Data(TraceEventType eventType, int id, params object[] data)
		{
			Source.TraceData(eventType, id, data);
		}

		public void Data(TraceEventType eventType, int id, object data)
		{
			Source.TraceData(eventType, id, data);
		}

		public void Event(TraceEventType eventType, int id, string message)
		{
			Source.TraceEvent(eventType, id, message);
		}

		public void Error(string format, params object[] args)
		{
			Error(0, format, args);
		}

		public void Error(int id, string format, params object[] args)
		{
			Event(TraceEventType.Error, id, format, args);
		}

		public void Information(string format, params object[] args)
		{
			Information(0, format, args);
		}

		public void Information(int id, string format, params object[] args)
		{
			Event(TraceEventType.Information, id, format, args);
		}

		public void Warning(string format, params object[] args)
		{
			Warning(0, format, args);
		}

		public void Warning(int id, string format, params object[] args)
		{
			Event(TraceEventType.Warning, id, format, args);
		}

		public void Verbose(string format, params object[] args)
		{
			Verbose(0, format, args);
		}

		public void Verbose(int id, string format, params object[] args)
		{
			Event(TraceEventType.Verbose, id, format, args);
		}

		public void Start(int id, string format)
		{
			Event(TraceEventType.Start, id, format);
		}

		public void Start(int id, string format, params object[] args)
		{
			Event(TraceEventType.Start, id, format, args);
		}


		public void Stop(int id, string format)
		{
			Event(TraceEventType.Stop, id, format);
		}

		public void Stop(int id, string format, params object[] args)
		{
			Event(TraceEventType.Stop, id, format, args);
		}



		public void Event(TraceEventType eventType, int id, string format, params object[] args)
		{
			if (args == null || args.Length == 0)
			{
				Source.TraceEvent(eventType, id, format);
			}
			else
			{
				Source.TraceEvent(eventType, id, format, args);
			}
		}

		public void Transfer(int eventId, Guid targetActivityId, string message, params object[] args)
		{
			Source.TraceTransfer(eventId, string.Format(message, args), targetActivityId);
			ActivityId = targetActivityId;
		}

	}
}